`timescale 1ns / 1ps

`include "data_width.vh"

module Accelerator_Top #(parameter
    DST_ID_DWIDTH               = `DST_ID_DWIDTH,
    DST_ID_ST                   = `DST_ID_ST,
    MEM_AWIDTH                  = `MEM_AWIDTH,
    MEM_DWIDTH                  = `MEM_DWIDTH,
    MEM_PER_DWIDTH              = `MEM_PER_DWIDTH,

    EDGE_OFF_DWIDTH             = `EDGE_OFF_DWIDTH,
    SRC_ID_DWIDTH               = `SRC_ID_DWIDTH,
    SRC_P_AWIDTH                = `SRC_P_AWIDTH,

    VERTEX_PIPE_NUM             = `VERTEX_PIPE_NUM,
    VERTEX_BRAM_NUM             = `VERTEX_BRAM_NUM,
    EDGE_PIPE_NUM               = `EDGE_PIPE_NUM,

    VERTEX_MASK_WIDTH           = `VERTEX_MASK_WIDTH,

    ACC_ID_WIDTH                = `ACC_ID_WIDTH,
    TOT_ACC_ID_WIDTH            = `TOT_ACC_ID_WIDTH,
    TOT_EDGE_MASK_WIDTH         = `TOT_EDGE_MASK_WIDTH,
    REQ_WIDTH                   = `REQ_WIDTH,
    REORDER_LOC_Y_WIDTH         = `REORDER_LOC_Y_WIDTH,
    WB_VALID_WIDTH              = `WB_VALID_WIDTH,
    VERTEX_BRAM_DWIDTH          = `VERTEX_BRAM_DWIDTH,
    VERTEX_BRAM_AWIDTH          = `VERTEX_BRAM_AWIDTH,
    VERTEX_BRAM_NUM_WIDTH       = `VERTEX_BRAM_NUM_WIDTH,

    OFFSET_CHANNEL_WIDTH        = `OFFSET_CHANNEL_WIDTH,
    INFO_CHANNEL_WIDTH          = `INFO_CHANNEL_WIDTH,
    VERTEX_DATA_CHANNEL_WIDTH   = `VERTEX_DATA_CHANNEL_WIDTH,
    VERTEX_ID_CHANNEL_WIDTH     = `VERTEX_ID_CHANNEL_WIDTH,
    CYCLE_CHANNEL_WIDTH         = `CYCLE_CHANNEL_WIDTH,

    ACC_INI_CYCLE               = `ACC_INI_CYCLE,
    RST_INI_CYCLE               = `RST_INI_CYCLE
    ) (
        input                                   kernel_clk,
        input                                   kernel_rst,
        input [31 : 0]                          ctrl_constant,
        input                                   ctrl_start,
        input [31 : 0]                          iterator_max,
        input [31 : 0]                          vertex_num,
        input [31 : 0]                          edge_num,
        input                                   wr_done,

        input                                   s_Offset_axis_tvalid_1,
        input                                   s_Offset_axis_tvalid_2,
        input [OFFSET_CHANNEL_WIDTH - 1 : 0]    s_Offset_axis_tdata_1,
        input [OFFSET_CHANNEL_WIDTH - 1 : 0]    s_Offset_axis_tdata_2,
        input                                   s_Offset_axis_tlast_1,
        input                                   s_Offset_axis_tlast_2,
        output                                  s_Offset_axis_tready_1,
        output                                  s_Offset_axis_tready_2,

        input                                   s_Info_axis_tvalid_1,
        input                                   s_Info_axis_tvalid_2,
        input [INFO_CHANNEL_WIDTH - 1 : 0]      s_Info_axis_tdata_1,
        input [INFO_CHANNEL_WIDTH - 1 : 0]      s_Info_axis_tdata_2,
        input                                   s_Info_axis_tlast_1,
        input                                   s_Info_axis_tlast_2,
        output                                  s_Info_axis_tready_1,
        output                                  s_Info_axis_tready_2,

        input                                       m_Vertex_Data_axis_aclk,
        output                                      m_Vertex_Data_axis_tvalid,
        input                                       m_Vertex_Data_axis_tready,
        output [VERTEX_DATA_CHANNEL_WIDTH - 1 : 0]  m_Vertex_Data_axis_tdata,
        output                                      m_Vertex_Data_axis_tlast,
        
        input                                       m_Vertex_Id_axis_aclk_1,
        input                                       m_Vertex_Id_axis_aclk_2,
        input                                       m_Vertex_Id_axis_aclk_3,
        input                                       m_Vertex_Id_axis_aclk_4,
        output                                      m_Vertex_Id_axis_tvalid_1,
        output                                      m_Vertex_Id_axis_tvalid_2,
        output                                      m_Vertex_Id_axis_tvalid_3,
        output                                      m_Vertex_Id_axis_tvalid_4,
        output [VERTEX_ID_CHANNEL_WIDTH - 1 : 0]    m_Vertex_Id_axis_tdata_1,
        output [VERTEX_ID_CHANNEL_WIDTH - 1 : 0]    m_Vertex_Id_axis_tdata_2,
        output [VERTEX_ID_CHANNEL_WIDTH - 1 : 0]    m_Vertex_Id_axis_tdata_3,
        output [VERTEX_ID_CHANNEL_WIDTH - 1 : 0]    m_Vertex_Id_axis_tdata_4,
        output                                      m_Vertex_Id_axis_tlast_1,
        output                                      m_Vertex_Id_axis_tlast_2,
        output                                      m_Vertex_Id_axis_tlast_3,
        output                                      m_Vertex_Id_axis_tlast_4,
        input                                       m_Vertex_Id_axis_tready_1,
        input                                       m_Vertex_Id_axis_tready_2,
        input                                       m_Vertex_Id_axis_tready_3,
        input                                       m_Vertex_Id_axis_tready_4,

        input                                       m_Cycle_axis_aclk,
        output                                      m_Cycle_axis_tvalid,
        output [CYCLE_CHANNEL_WIDTH - 1 : 0]        m_Cycle_axis_tdata,
        output                                      m_Cycle_axis_tlast,
        input                                       m_Cycle_axis_tready,
        
        output                                      acc_start,  // 控制读写通道开始
        output                                      wr_cn_rst,  // from M17
        output                                      rd_cn_rst); // from M3

    // initial parameter
    wire                                               M0_rst;
    wire [DST_ID_DWIDTH - 1 : 0]                       M0_dst_id_ed;
    wire [DST_ID_DWIDTH - 1 : 0]                       M0_vertex_num;
    wire [EDGE_OFF_DWIDTH - 1 : 0]                     M0_edge_off_ed;
    wire [MEM_AWIDTH - 1 : 0]                          M0_edge_off_addr_ed;
    wire [MEM_AWIDTH - 1 : 0]                          M0_edge_info_addr_ed;
    wire [EDGE_OFF_DWIDTH - VERTEX_MASK_WIDTH - 1 : 0] M0_mem_edge_ed;
    wire                                               M0_para_valid;

    // get_dst_id
    wire                                               M1_rst;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]     M1_dst_id;
    wire [VERTEX_PIPE_NUM - 1 : 0]                     M1_dst_data_valid;
    wire [DST_ID_DWIDTH - 1 : 0]                       M1_dst_id_ed;
    wire [EDGE_OFF_DWIDTH - 1 : 0]                     M1_edge_off_ed;
    wire [MEM_AWIDTH - 1 : 0]                          M1_edge_off_addr_ed;
    wire [MEM_AWIDTH - 1 : 0]                          M1_edge_info_addr_ed;
    wire [EDGE_OFF_DWIDTH - VERTEX_MASK_WIDTH - 1 : 0] M1_mem_edge_ed;
    wire M1_para_valid;

    // rd_edge_off
    wire                                               M2_rst;
    wire [DST_ID_DWIDTH - 1 : 0]                       M2_dst_id_ed;
    wire [EDGE_OFF_DWIDTH - 1 : 0]                     M2_edge_off_ed;
    wire [MEM_AWIDTH - 1 : 0]                          M2_edge_info_addr_ed;
    wire [EDGE_OFF_DWIDTH - VERTEX_MASK_WIDTH - 1 : 0] M2_mme_edge_ed;
    wire                                               M2_para_valid;
    wire                                               M2_buffer_full_vertex;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]     M2_dst_id;
    wire [VERTEX_PIPE_NUM - 1 : 0]                     M2_dst_data_valid;
    wire [MEM_AWIDTH - 1 : 0]                          M2_rd_edge_off_addr;
    wire                                               M2_rd_edge_off_valid;

    // double_mem_interface : 对比于原版本增加了一个内存接口
    wire                                               MEM_IF_rst;
    wire                                               MEM_IF_addr_buffer_full;
    wire [MEM_DWIDTH * 2 - 1 : 0]                          MEM_IF_mem_data_to_edge_off;
    wire [MEM_DWIDTH * 2 - 1 : 0]                          MEM_IF_mem_data_to_edge_info;
    wire                                               MEM_IF_mem_data_valid_to_edge_off;
    wire                                               MEM_IF_mem_data_valid_to_edge_info;
    wire [MEM_AWIDTH - 1 : 0]                          MEM_IF_addr_offset;
    wire [MEM_AWIDTH - 1 : 0]                          MEM_IF_addr_info;
    wire                                               MEM_IF_addr_offset_valid;
    wire                                               MEM_IF_addr_info_valid;

    // 使用axi4协议访问 global memory
    wire                                               MEM_mem_rst;
    wire                                               MEM_mem_full;
    wire [MEM_DWIDTH * 2 - 1 : 0]                          MEM_mem_data_offset;
    wire [MEM_DWIDTH * 2 - 1 : 0]                          MEM_mem_data_info;
    wire [MEM_AWIDTH - 1 : 0]                          MEM_mem_addr_offset;
    wire [MEM_AWIDTH - 1 : 0]                          MEM_mem_addr_info;
    wire                                               MEM_mem_data_valid_offset;
    wire                                               MEM_mem_data_valid_info;

    // get_edge_off
    wire                                                   M3_rst;
    wire [MEM_AWIDTH - 1 : 0]                              M3_edge_info_addr_ed;
    wire [EDGE_OFF_DWIDTH - 1 : 0]                         M3_edge_off_ed;
    wire [EDGE_OFF_DWIDTH - VERTEX_MASK_WIDTH - 1 : 0]     M3_mem_edge_ed;
    wire                                                   M3_para_valid;
    wire                                                   M3_rd_plus_valid;
    wire                                                   M3_buffer_full_vertex;
    wire [EDGE_OFF_DWIDTH * (VERTEX_PIPE_NUM + 1) - 1 : 0] M3_edge_off;
    wire [DST_ID_DWIDTH *VERTEX_PIPE_NUM - 1 : 0]          M3_dst_id;
    wire [VERTEX_PIPE_NUM - 1 : 0]                         M3_dst_data_valid;

    // edge_info_pre
    wire                                               M4_rst;
    wire [MEM_AWIDTH - 1 : 0]                          M4_edge_info_addr_ed;
    wire [EDGE_OFF_DWIDTH - 1 : 0]                     M4_edge_off_ed;
    wire [EDGE_OFF_DWIDTH - VERTEX_MASK_WIDTH - 1 : 0] M4_mem_edge_ed;
    wire                                               M4_para_valid;
    wire                                               M4_buffer_full_vertex;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]     M4_dst_id;
    wire [EDGE_OFF_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]   M4_edge_off_l;
    wire [EDGE_OFF_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]   M4_edge_off_r;
    wire [VERTEX_PIPE_NUM - 1 : 0]                     M4_dst_data_valid;

    // rd_edge_info
    wire                                               M5_rst;
    wire                                               M5_buffer_full_vertex;
    wire [MEM_AWIDTH - 1 : 0]                          M5_rd_edge_info_addr;
    wire                                               M5_rd_edge_info_valid;
    wire                                               M5_finish_read;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]     M5_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0] M5_edge_info_mask_l;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0] M5_edge_info_mask_r;
    wire [VERTEX_PIPE_NUM - 1 : 0]                     M5_dst_data_valid;

    // get_edge_info_pre_0
    wire                                                M6_0_rst;
    wire                                                M6_0_buffer_full_vertex;
    wire                                                M6_0_any_dst_data_valid;
    wire                                                M6_0_finish_read;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]      M6_0_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0]  M6_0_edge_info_mask_l;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0]  M6_0_edge_info_mask_r;
    wire [VERTEX_PIPE_NUM - 1 : 0]                      M6_0_dst_data_valid;

    // get_edge_info_pre_1
    wire                                                 M6_1_rst;
    wire                                                 M6_1_buffer_full_vertex;
    wire                                                 M6_1_finish_read;
    wire                                                 M6_1_any_dst_data_valid;
    wire [TOT_EDGE_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0] M6_1_tot_src_p_mask;
    wire [TOT_ACC_ID_WIDTH * VERTEX_PIPE_NUM - 1 : 0]    M6_1_tot_acc_id;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]       M6_1_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0]   M6_1_src_p_mask_r;
    wire [VERTEX_PIPE_NUM - 1 : 0]                       M6_1_dst_data_valid;

    // get_edge_info_pre_2
    wire                                                       M6_2_rst;
    wire                                                       M6_2_buffer_full_vertex;
    wire                                                       M6_2_finish_read;
    wire                                                       M6_2_any_dst_data_valid;
    wire [TOT_EDGE_MASK_WIDTH * (VERTEX_PIPE_NUM / 2) - 1 : 0] M6_2_tot_src_p_mask;
    wire [TOT_ACC_ID_WIDTH * (VERTEX_PIPE_NUM / 2) - 1 : 0]    M6_2_tot_acc_id;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]             M6_2_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0]         M6_2_src_p_mask_r;
    wire [VERTEX_PIPE_NUM - 1 : 0]                             M6_2_dst_data_valid;

    // get_edge_info_pre_3
    wire                                                       M6_3_rst;
    wire                                                       M6_3_buffer_full_vertex;
    wire                                                       M6_3_finish_read;
    wire                                                       M6_3_any_dst_data_valid;
    wire [TOT_EDGE_MASK_WIDTH * (VERTEX_PIPE_NUM / 4) - 1 : 0] M6_3_tot_src_p_mask;
    wire [TOT_ACC_ID_WIDTH * (VERTEX_PIPE_NUM / 4) - 1 : 0]    M6_3_tot_acc_id;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]             M6_3_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0]         M6_3_src_p_mask_r;
    wire [VERTEX_PIPE_NUM - 1 : 0]                             M6_3_dst_data_valid;

    // get_edge_info_pre_4
    wire                                                       M6_4_rst;
    wire                                                       M6_4_buffer_full_vertex;
    wire                                                       M6_4_finish_read;
    wire                                                       M6_4_any_dst_data_valid;
    wire [TOT_EDGE_MASK_WIDTH * (VERTEX_PIPE_NUM / 8) - 1 : 0] M6_4_tot_src_p_mask;
    wire [TOT_ACC_ID_WIDTH * (VERTEX_PIPE_NUM / 8) - 1 : 0]    M6_4_tot_acc_id;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]             M6_4_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0]         M6_4_src_p_mask_r;
    wire [VERTEX_PIPE_NUM - 1 : 0]                             M6_4_dst_data_valid;

    // get_edge_info_pre_5
    wire                                                        M6_5_rst;
    wire                                                        M6_5_buffer_full_vertex;
    wire                                                        M6_5_finish_read;
    wire                                                        M6_5_any_dst_data_valid;
    wire [TOT_EDGE_MASK_WIDTH * (VERTEX_PIPE_NUM / 16) - 1 : 0] M6_5_tot_src_p_mask;
    wire [TOT_ACC_ID_WIDTH * (VERTEX_PIPE_NUM / 16) - 1 : 0]    M6_5_tot_acc_id;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]              M6_5_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0]          M6_5_src_p_mask_r;
    wire [VERTEX_PIPE_NUM - 1 : 0]                              M6_5_dst_data_valid;

    // get_edge_info
    wire                                               M7_rst;
    wire                                               M7_rd_plus_valid;
    wire                                               M7_buffer_full_vertex;
    wire [SRC_ID_DWIDTH * EDGE_PIPE_NUM - 1 : 0]       M7_src_id;
    wire                                               M7_src_data_valid;
    wire [TOT_EDGE_MASK_WIDTH - 1 : 0]                 M7_tot_src_p_mask;
    wire [TOT_ACC_ID_WIDTH - 1 : 0]                    M7_tot_acc_id;
    wire                                               M7_any_dst_data_valid;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]     M7_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0] M7_src_p_mask_r;
    wire [VERTEX_PIPE_NUM - 1 : 0]                     M7_dst_data_valid;

    // rd_src_p
    wire                                               M8_rst;
    wire                                               M8_buffer_full_any;
    wire [SRC_P_AWIDTH * EDGE_PIPE_NUM - 1 : 0]        M8_rd_src_p_addr;
    wire                                               M8_rd_src_p_valid;
    wire [TOT_EDGE_MASK_WIDTH - 1 : 0]                 M8_tot_src_p_mask;
    wire [TOT_ACC_ID_WIDTH - 1 : 0]                    M8_tot_acc_id;
    wire                                               M8_any_dst_data_valid;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]     M8_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0] M8_src_p_mask_r;
    wire [VERTEX_PIPE_NUM - 1 : 0]                     M8_dst_data_valid;

    // rd_src_p_shuffle_block_1
    /* no need for reuse
    wire M9_1_buffer_full_edge, M9_1_buffer_full_vertex;
    wire [TOT_REUSE_WIDTH - 1 : 0] M9_1_reuse_info;
    wire [EDGE_PIPE_NUM - 1 : 0] M9_1_reuse_valid;
    wire [SRC_P_AWIDTH * EDGE_PIPE_NUM - 1 : 0] M9_1_rd_src_p_addr;
    wire M9_1_rd_src_p_valid;
    wire [TOT_EDGE_MASK_WIDTH - 1 : 0] M9_1_tot_src_p_mask;
    wire [TOT_ACC_ID_WIDTH - 1 : 0] M9_1_tot_acc_id;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0] M9_1_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0] M9_1_src_p_mask_r;
    wire [VERTEX_PIPE_NUM - 1 : 0] M9_1_dst_data_valid;
    */

    // rd_src_p_shuffle_block_2
    wire                                               M9_2_rst;
    wire                                               M9_2_buffer_full_edge;
    wire                                               M9_2_buffer_full_vertex;
    wire [SRC_P_AWIDTH * EDGE_PIPE_NUM - 1 : 0]        M9_2_rd_src_p_addr;
    wire                                               M9_2_rd_src_p_valid;
    // wire [TOT_REUSE_WIDTH - 1 : 0]                     M9_2_reuse_info;
    // wire [EDGE_PIPE_NUM - 1 : 0]                       M9_2_reuse_valid;
    wire [REQ_WIDTH - 1 : 0]                           M9_2_req_num;
    wire [TOT_EDGE_MASK_WIDTH - 1 : 0]                 M9_2_tot_src_p_mask;
    wire [TOT_ACC_ID_WIDTH - 1 : 0]                    M9_2_tot_acc_id;
    wire                                               M9_2_any_dst_data_valid;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]     M9_2_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0] M9_2_src_p_mask_r;
    wire [VERTEX_PIPE_NUM - 1 : 0]                     M9_2_dst_data_valid;

    // rd_src_p_shuffle_block_3
    wire                                                 M9_3_rst;
    wire                                                 M9_3_buffer_full_edge;
    wire                                                 M9_3_buffer_full_vertex;
    wire                                                 M9_3_rd_src_p_addr_finish;
    wire [VERTEX_BRAM_AWIDTH * VERTEX_BRAM_NUM - 1 : 0]  M9_3_rd_src_p_addr;
    wire [REORDER_LOC_Y_WIDTH * VERTEX_BRAM_NUM - 1 : 0] M9_3_reorder_loc_y;
    wire [VERTEX_BRAM_NUM - 1 : 0]                       M9_3_rd_src_p_valid;
    // wire [TOT_REUSE_WIDTH - 1 : 0]                       M9_3_reuse_info;
    // wire [EDGE_PIPE_NUM - 1 : 0]                         M9_3_reuse_valid;
    wire [TOT_EDGE_MASK_WIDTH - 1 : 0]                   M9_3_tot_src_p_mask;
    wire [TOT_ACC_ID_WIDTH - 1 : 0]                      M9_3_tot_acc_id;
    wire                                                 M9_3_any_dst_data_valid;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]       M9_3_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0]   M9_3_src_p_mask_r;
    wire [VERTEX_PIPE_NUM - 1 : 0]                       M9_3_dst_data_valid;

    // rd_src_p_bram_block
    wire                                                 M10_rst;
    wire                                                 M10_buffer_full_vertex;
    wire [VERTEX_BRAM_DWIDTH * VERTEX_BRAM_NUM - 1 : 0]  M10_src_p;
    wire [REORDER_LOC_Y_WIDTH * VERTEX_BRAM_NUM - 1 : 0] M10_reorder_loc_y;
    wire [VERTEX_BRAM_NUM - 1 : 0]                       M10_src_p_valid;
    // wire [TOT_REUSE_WIDTH - 1 : 0]                       M10_reuse_info;
    // wire [EDGE_PIPE_NUM - 1 : 0]                         M10_reuse_valid;
    wire                                                 M10_rd_src_p_addr_finish;
    wire [TOT_EDGE_MASK_WIDTH - 1 : 0]                   M10_tot_src_p_mask;
    wire [TOT_ACC_ID_WIDTH - 1 : 0]                      M10_tot_acc_id;
    wire                                                 M10_any_dst_data_valid;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]       M10_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0]   M10_src_p_mask_r;
    wire [VERTEX_PIPE_NUM - 1 : 0]                       M10_dst_data_valid;

    // rd_src_p_reorder_block_1
    wire                                                M11_1_rst;
    wire                                                M11_1_buffer_full_vertex;
    wire [VERTEX_BRAM_DWIDTH * VERTEX_BRAM_NUM - 1 : 0] M11_1_src_p;
    wire [VERTEX_BRAM_NUM - 1 : 0]                      M11_1_src_p_valid;
    // wire [TOT_REUSE_WIDTH - 1 : 0]                      M11_1_reuse_info;
    // wire [EDGE_PIPE_NUM - 1 : 0]                        M11_1_reuse_valid;
    wire                                                M11_1_rd_src_p_addr_finish;
    wire [TOT_EDGE_MASK_WIDTH - 1 : 0]                  M11_1_tot_src_p_mask;
    wire [TOT_ACC_ID_WIDTH - 1 : 0]                     M11_1_tot_acc_id;
    wire                                                M11_1_any_dst_data_valid;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]      M11_1_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0]  M11_1_src_p_mask_r;
    wire [VERTEX_PIPE_NUM - 1 : 0]                      M11_1_dst_data_valid;

    // rd_src_p_reorder_block_2
    wire                                               M11_2_rst;
    wire                                               M11_2_buffer_full_vertex;
    wire [VERTEX_BRAM_DWIDTH * EDGE_PIPE_NUM - 1 : 0]  M11_2_src_p;
    // wire [TOT_REUSE_WIDTH - 1 : 0]                     M11_2_reuse_info;
    // wire [EDGE_PIPE_NUM - 1 : 0]                       M11_2_reuse_valid;
    wire                                               M11_2_src_p_valid;
    wire [TOT_EDGE_MASK_WIDTH - 1 : 0]                 M11_2_tot_src_p_mask;
    wire [TOT_ACC_ID_WIDTH - 1 : 0]                    M11_2_tot_acc_id;
    wire                                               M11_2_any_dst_data_valid;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]     M11_2_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0] M11_2_src_p_mask_r;
    wire [VERTEX_PIPE_NUM - 1 : 0]                     M11_2_dst_data_valid;

    // rd_src_p_reorder_block_3
    /* no need for reuse
    wire M11_3_buffer_full_vertex, M11_3_buffer_full_edge;
    wire [VERTEX_BRAM_DWIDTH * EDGE_PIPE_NUM - 1 : 0] M11_3_src_p;
    wire M11_3_src_p_valid;
    wire [TOT_EDGE_MASK_WIDTH - 1 : 0] M11_3_tot_src_p_mask;
    wire [TOT_ACC_ID_WIDTH - 1 : 0] M11_3_tot_acc_id;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0] M11_3_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0] M11_3_src_p_mask_r;
    wire [VERTEX_PIPE_NUM - 1 : 0] M11_3_dst_data_valid;
    */

    // schedule
    wire                                               M12_rst;
    wire                                               M12_buffer_full_edge;
    wire                                               M12_buffer_full_vertex;
    wire [VERTEX_BRAM_DWIDTH * EDGE_PIPE_NUM - 1 : 0]  M12_src_p;
    wire [TOT_EDGE_MASK_WIDTH - 1 : 0]                 M12_src_p_mask;
    wire [TOT_ACC_ID_WIDTH - 1 : 0]                    M12_tot_acc_id;
    wire                                               M12_src_p_valid;
    wire [VERTEX_PIPE_NUM - 1 : 0]                     M12_data_valid;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]     M12_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0] M12_src_p_mask_r;
    wire [VERTEX_PIPE_NUM - 1 : 0]                     M12_dst_data_valid;


    /// edge_process
    wire                                               M13_rst;
    wire [VERTEX_BRAM_DWIDTH * EDGE_PIPE_NUM - 1 : 0]  M13_src_p;
    wire [TOT_ACC_ID_WIDTH - 1 : 0]                    M13_tot_acc_id;
    wire                                               M13_src_p_valid;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]     M13_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0] M13_src_p_mask_r;
    wire [VERTEX_PIPE_NUM - 1 : 0]                     M13_dst_data_valid;

    // parallel_accumulator
    wire                                               M14_rst;
    wire [VERTEX_BRAM_DWIDTH * EDGE_PIPE_NUM - 1 : 0]  M14_src;
    wire                                               M14_src_valid;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]     M14_dst_id;
    wire [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0] M14_src_mask;
    wire [VERTEX_PIPE_NUM - 1 : 0]                     M14_dst_data_valid;

    // multiplexer
    wire                                                M15_rst;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]      M15_dst_id;
    wire [VERTEX_BRAM_DWIDTH * VERTEX_PIPE_NUM - 1 : 0] M15_src;
    wire [VERTEX_PIPE_NUM - 1 : 0]                      M15_dst_data_valid;

    // sequential_accumulator
    wire                                                M16_rst;
    wire [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]      M16_wb_dst_addr;
    wire [VERTEX_BRAM_DWIDTH * VERTEX_PIPE_NUM - 1 : 0] M16_wb_dst_data;
    wire [WB_VALID_WIDTH * VERTEX_PIPE_NUM - 1 : 0]     M16_wb_dst_data_valid;

    // store data to avoid timing failed
    // (* dont_touch = "yes" *) reg [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]      M16_wb_dst_addr_reg;
    // (* dont_touch = "yes" *) reg [VERTEX_BRAM_DWIDTH * VERTEX_PIPE_NUM - 1 : 0] M16_wb_dst_data_reg;
    // (* dont_touch = "yes" *) reg [WB_VALID_WIDTH * VERTEX_PIPE_NUM - 1 : 0]     M16_wb_dst_data_valid_reg;

    // additional information
    reg [31 : 0]                        iterator_max_r       = 32'h1; // load iterate number
    reg [31 : 0]                        iterator_count       = 0;     // count iterate number
    reg [31 : 0]                        cycle_count_r        = 0;     // count cycles
    reg                                 acc_done             = 1'b0;
    reg signed [ACC_INI_CYCLE - 1 : 0]  acc_running   = 0;  // stop ACC_INI_CYCLE when ctrl_start is assert.
    reg [RST_INI_CYCLE - 1 : 0]         rst_initial          = {RST_INI_CYCLE{1'b1}};
    // wire rst = kernel_rst; // 去掉 rst 信号，直接使用 ctrl_start 来初始化 rst 信号

    wire clk = kernel_clk;
    wire rst = rst_initial[RST_INI_CYCLE - 1];

    // initial rst
    // rst 从 0_initial 逐层传递
    always @ (posedge clk) begin
        if (ctrl_start) begin
            rst_initial <= {{(RST_INI_CYCLE - 1){1'b1}}, 1'b0};
        end
        else begin
            rst_initial <= rst_initial << 1;
        end
    end
    // initial rst

    // load initial register.
    always @ (posedge clk) begin
        if (ctrl_start) begin
            iterator_max_r <= iterator_max;
        end
    end
    // load initial register.

    // initial running.
    always @ (posedge clk) begin
        if (ctrl_start) begin
            acc_running[ACC_INI_CYCLE - 2 : 0]  <= {(ACC_INI_CYCLE - 1){1'b0}};
            acc_running[ACC_INI_CYCLE - 1]      <= 1'b1;
            acc_done                            <= 1'b0;
        end
        else begin
            // 整体结束则将 acc_running 置初值，等待下次执行
            // 未结束则维持 acc_running[0] = true
            acc_running <= wr_done ? 0 : (acc_running >>> 1);
            acc_done    <= (acc_running[0] && (iterator_count > iterator_max_r)) ? 1'b1 : 1'b0;
        end
    end
    // acc_running[0] is true after ACC_INI_CYCLE cycles.

    always @ (posedge clk) begin
        if (rst) begin
            cycle_count_r  <= 0;
            iterator_count <= 0;
        end
        else begin
            cycle_count_r  <= acc_running[0] ? cycle_count_r + 1 : cycle_count_r;
            iterator_count <= (|M16_wb_dst_data_valid[2 * WB_VALID_WIDTH - 1 : WB_VALID_WIDTH] && M16_wb_dst_addr[2 * DST_ID_DWIDTH - 1 : DST_ID_DWIDTH] == 1 && acc_running[0]) ?
                              iterator_count + 1 :
                              iterator_count;
        end
    end
    // count cycle

    // control signal to read and write channel
    assign acc_start = acc_running[0];

    assign m_Cycle_axis_tvalid  = acc_done;
    assign m_Cycle_axis_tdata   = cycle_count_r;

    initial_const M0 (
        .clk                (clk),
        .front_rst          (rst),
        .ctrl_start         (ctrl_start),
        .front_vertex_num   (vertex_num),
        .front_edge_num     (edge_num),

        .rst                (M0_rst),
        .dst_id_ed          (M0_dst_id_ed),
        .vertex_num         (M0_vertex_num),
        .edge_off_ed        (M0_edge_off_ed),
        .edge_off_addr_ed   (M0_edge_off_addr_ed),
        .edge_info_addr_ed  (M0_edge_info_addr_ed),
        .mem_edge_ed        (M0_mem_edge_ed),
        .para_valid         (M0_para_valid));

    get_dst_id M1 (
        .clk                        (clk),
        .back_stage_vertex_full     (M2_buffer_full_vertex), // control vertex out

        // front parameter
        .front_rst                  (M0_rst),
        .front_dst_id_ed            (M0_dst_id_ed),
        .front_vertex_num           (M0_vertex_num),
        .front_edge_off_ed          (M0_edge_off_ed),
        .front_edge_off_addr_ed     (M0_edge_off_addr_ed),
        .front_edge_info_addr_ed    (M0_edge_info_addr_ed),
        .front_mem_edge_ed          (M0_mem_edge_ed),
        .front_para_valid           (M0_para_valid),

        // next parameter
        .rst                        (M1_rst),
        .dst_id_ed                  (M1_dst_id_ed),
        .edge_off_ed                (M1_edge_off_ed),
        .edge_off_addr_ed           (M1_edge_off_addr_ed),
        .edge_info_addr_ed          (M1_edge_info_addr_ed),
        .mem_edge_ed                (M1_mem_edge_ed),
        .para_valid                 (M1_para_valid),

        // next vertex pipeline
        .dst_id                     (M1_dst_id),
        .dst_data_valid             (M1_dst_data_valid));

    rd_edge_off M2 (
        .clk                        (clk),
        .buffer_full_vertex         (M2_buffer_full_vertex),    // control vertex in
        .back_stage_vertex_full     (M3_buffer_full_vertex),    // control vertex out

        // front vertex pipeline
        .front_dst_id               (M1_dst_id),
        .front_dst_data_valid       (M1_dst_data_valid),

        // to mem
        .mem_full                   (MEM_IF_addr_buffer_full),
        .addr_rev_rd_plus_valid     (M3_rd_plus_valid),         // control address out

        // front parameter
        .front_rst                  (M1_rst),
        .front_dst_id_ed            (M1_dst_id_ed),
        .front_edge_off_ed          (M1_edge_off_ed),
        .front_edge_off_addr_ed     (M1_edge_off_addr_ed),
        .front_edge_info_addr_ed    (M1_edge_info_addr_ed),
        .front_mem_edge_ed          (M1_mem_edge_ed),
        .front_para_valid           (M1_para_valid),

        // next parameter
        .rst                        (M2_rst),
        .dst_id_ed                  (M2_dst_id_ed),
        .edge_off_ed                (M2_edge_off_ed),
        .edge_info_addr_ed          (M2_edge_info_addr_ed),
        .mem_edge_ed                (M2_mme_edge_ed),
        .para_valid                 (M2_para_valid),

        // from mem
        .rd_edge_off_addr           (M2_rd_edge_off_addr),
        .rd_edge_off_valid          (M2_rd_edge_off_valid),

        // next vertex pipeline
        .dst_id                     (M2_dst_id),
        .dst_data_valid             (M2_dst_data_valid));

    // mem_interface of two channel
    double_mem_interface MEM_IF (
        .clk                        (clk),
        .front_rst                  (M2_rst),       // use M2 reset or M5 reset
        .rst                        (MEM_IF_rst),   // reset to mem
        // from M2
        .edge_off_addr              (M2_rd_edge_off_addr),
        .edge_off_addr_valid        (M2_rd_edge_off_valid),
        // from M5
        .edge_info_addr             (M5_rd_edge_info_addr),
        .edge_info_addr_valid       (M5_rd_edge_info_valid),

        // offset address to fpga mem
        .addr_offset                (MEM_IF_addr_offset),
        .addr_offset_valid          (MEM_IF_addr_offset_valid),
        // info address to fpga mem
        .addr_info                  (MEM_IF_addr_info),
        .addr_info_valid            (MEM_IF_addr_info_valid),
        // mem status from fpga mem
        .mem_full                   (MEM_mem_full),
        // offset data from fpga mem
        .mem_data_offset            (MEM_mem_data_offset),
        .mem_addr_offset            (MEM_mem_addr_offset),
        .mem_data_valid_offset      (MEM_mem_data_valid_offset),
        // info data from fpga mem
        .mem_data_info              (MEM_mem_data_info),
        .mem_addr_info              (MEM_mem_addr_info),
        .mem_data_valid_info        (MEM_mem_data_valid_info),

        // address buffer full to M3 and M7
        .addr_buffer_full           (MEM_IF_addr_buffer_full),
        // to M3
        .mem_data_to_edge_off       (MEM_IF_mem_data_to_edge_off),
        .mem_data_valid_to_edge_off (MEM_IF_mem_data_valid_to_edge_off),
        // to M7
        .mem_data_to_edge_info      (MEM_IF_mem_data_to_edge_info),
        .mem_data_valid_to_edge_info(MEM_IF_mem_data_valid_to_edge_info));

    double_fpga_mem MEM (
        .clk                        (clk),
        .front_rst                  (MEM_IF_rst),
        .rst                        (rd_cn_rst),

        // from axi
        .s_Offset_axis_tvalid_1     (s_Offset_axis_tvalid_1),
        .s_Offset_axis_tready_1     (s_Offset_axis_tready_1),
        .s_Offset_axis_tdata_1      (s_Offset_axis_tdata_1),
        .s_Offset_axis_tlast_1      (s_Offset_axis_tlast_1),

        .s_Offset_axis_tvalid_2     (s_Offset_axis_tvalid_2),
        .s_Offset_axis_tready_2     (s_Offset_axis_tready_2),
        .s_Offset_axis_tdata_2      (s_Offset_axis_tdata_2),
        .s_Offset_axis_tlast_2      (s_Offset_axis_tlast_2),

        .s_Info_axis_tvalid_1       (s_Info_axis_tvalid_1),
        .s_Info_axis_tready_1       (s_Info_axis_tready_1),
        .s_Info_axis_tdata_1        (s_Info_axis_tdata_1),
        .s_Info_axis_tlast_1        (s_Info_axis_tlast_1),

        .s_Info_axis_tvalid_2       (s_Info_axis_tvalid_2),
        .s_Info_axis_tready_2       (s_Info_axis_tready_2),
        .s_Info_axis_tdata_2        (s_Info_axis_tdata_2),
        .s_Info_axis_tlast_2        (s_Info_axis_tlast_2),

        // from mem interface
        .addr_offset                (MEM_IF_addr_offset),
        .addr_offset_valid          (MEM_IF_addr_offset_valid),
        .addr_info                  (MEM_IF_addr_info),
        .addr_info_valid            (MEM_IF_addr_info_valid),

        // to mem interface
        .mem_full                   (MEM_mem_full),
        .mem_data_offset            (MEM_mem_data_offset),
        .mem_addr_offset            (MEM_mem_addr_offset),
        .mem_data_valid_offset      (MEM_mem_data_valid_offset),
        .mem_data_info              (MEM_mem_data_info),
        .mem_addr_info              (MEM_mem_addr_info),
        .mem_data_valid_info        (MEM_mem_data_valid_info));

    get_edge_off M3 (
        .clk                        (clk),
        .mem_data                   (MEM_IF_mem_data_to_edge_off),
        .mem_data_valid             (MEM_IF_mem_data_valid_to_edge_off),
        .front_dst_id               (M2_dst_id),
        .front_dst_data_valid       (M2_dst_data_valid),
        .back_stage_vertex_full     (M4_buffer_full_vertex),

        .front_rst                  (M2_rst),
        .front_dst_id_ed            (M2_dst_id_ed),
        .front_edge_off_ed          (M2_edge_off_ed),
        .front_edge_info_addr_ed    (M2_edge_info_addr_ed),
        .front_mem_edge_ed          (M2_mme_edge_ed),
        .front_para_valid           (M2_para_valid),

        .rst                        (M3_rst),
        .edge_info_addr_ed          (M3_edge_info_addr_ed),
        .edge_off_ed                (M3_edge_off_ed),
        .mem_edge_ed                (M3_mem_edge_ed),
        .para_valid                 (M3_para_valid),

        .rd_plus_valid              (M3_rd_plus_valid),
        .buffer_full_vertex         (M3_buffer_full_vertex),
        .edge_off                   (M3_edge_off),
        .dst_id                     (M3_dst_id),
        .dst_data_valid             (M3_dst_data_valid));

    edge_info_pre M4 (
        .clk                        (clk),
        .front_edge_off             (M3_edge_off),
        .front_dst_id               (M3_dst_id),
        .front_dst_data_valid       (M3_dst_data_valid),
        .back_stage_vertex_full     (M5_buffer_full_vertex),

        .front_rst                  (M3_rst),
        .front_edge_off_ed          (M3_edge_off_ed),
        .front_edge_info_addr_ed    (M3_edge_info_addr_ed),
        .front_mem_edge_ed          (M3_mem_edge_ed),
        .front_para_valid           (M3_para_valid),
        
        .rst                        (M4_rst),
        .edge_off_ed                (M4_edge_off_ed),
        .edge_info_addr_ed          (M4_edge_info_addr_ed),
        .mem_edge_ed                (M4_mem_edge_ed),
        .para_valid                 (M4_para_valid),

        .buffer_full_vertex         (M4_buffer_full_vertex),
        .dst_id                     (M4_dst_id),
        .edge_off_l                 (M4_edge_off_l),
        .edge_off_r                 (M4_edge_off_r),
        .dst_data_valid             (M4_dst_data_valid));

    rd_edge_info M5 (
        .clk                        (clk),
        .front_dst_id               (M4_dst_id),
        .front_edge_off_l           (M4_edge_off_l),
        .front_edge_off_r           (M4_edge_off_r),
        .front_dst_data_valid       (M4_dst_data_valid),
        .mem_full                   (MEM_IF_addr_buffer_full),
        .addr_rev_rd_plus_valid     (M7_rd_plus_valid),
        .back_stage_vertex_full     (M6_1_buffer_full_vertex),

        .front_rst                  (M4_rst),
        .front_edge_off_ed          (M4_edge_off_ed),
        .front_edge_info_addr_ed    (M4_edge_info_addr_ed),
        .front_mem_edge_ed          (M4_mem_edge_ed),
        .front_para_valid           (M4_para_valid),

        .rst                        (M5_rst),

        .buffer_full_vertex         (M5_buffer_full_vertex),
        .rd_edge_info_addr          (M5_rd_edge_info_addr),
        .rd_edge_info_valid         (M5_rd_edge_info_valid),
        .finish_read                (M5_finish_read),
        .dst_id                     (M5_dst_id),
        .edge_info_mask_l           (M5_edge_info_mask_l),
        .edge_info_mask_r           (M5_edge_info_mask_r),
        .dst_data_valid             (M5_dst_data_valid));
    
    get_edge_info_pre_0 M6_0 (
        .clk                        (clk),
        .front_finish_read          (M5_finish_read),
        .front_dst_id               (M5_dst_id),
        .front_edge_info_mask_l     (M5_edge_info_mask_l),
        .front_edge_info_mask_r     (M5_edge_info_mask_r),
        .front_dst_data_valid       (M5_dst_data_valid),
        .back_stage_vertex_full     (M6_1_buffer_full_vertex),

        .front_rst                  (M5_rst),
        .rst                        (M6_0_rst),

        .finish_read                (M6_0_finish_read),
        .any_dst_data_valid         (M6_0_any_dst_data_valid),
        .dst_id                     (M6_0_dst_id),
        .edge_info_mask_l           (M6_0_edge_info_mask_l),
        .edge_info_mask_r           (M6_0_edge_info_mask_r),
        .dst_data_valid             (M6_0_dst_data_valid),
        .buffer_full_vertex         (M6_0_buffer_full_vertex));

    get_edge_info_pre_1 M6_1 (
        .clk                        (clk),
        .front_finish_read          (M6_0_finish_read),
        .front_any_dst_data_valid   (M6_0_any_dst_data_valid),
        .front_dst_id               (M6_0_dst_id),
        .front_edge_info_mask_l     (M6_0_edge_info_mask_l),
        .front_edge_info_mask_r     (M6_0_edge_info_mask_r),
        .front_dst_data_valid       (M6_0_dst_data_valid),
        .back_stage_vertex_full     (M6_2_buffer_full_vertex),

        .front_rst                  (M6_0_rst),
        .rst                        (M6_1_rst),

        .buffer_full_vertex         (M6_1_buffer_full_vertex),
        .finish_read                (M6_1_finish_read),
        .any_dst_data_valid         (M6_1_any_dst_data_valid),
        .tot_src_p_mask             (M6_1_tot_src_p_mask),
        .tot_acc_id                 (M6_1_tot_acc_id),
        .dst_id                     (M6_1_dst_id),
        .src_p_mask_r               (M6_1_src_p_mask_r),
        .dst_data_valid             (M6_1_dst_data_valid));

    get_edge_info_pre_2 M6_2 (
        .clk                        (clk),
        .front_finish_read          (M6_1_finish_read),
        .front_any_dst_data_valid   (M6_1_any_dst_data_valid),
        .front_tot_src_p_mask       (M6_1_tot_src_p_mask),
        .front_tot_acc_id           (M6_1_tot_acc_id),
        .front_dst_id               (M6_1_dst_id),
        .front_src_p_mask_r         (M6_1_src_p_mask_r),
        .front_dst_data_valid       (M6_1_dst_data_valid),
        .back_stage_vertex_full     (M6_3_buffer_full_vertex),

        .front_rst                  (M6_1_rst),
        .rst                        (M6_2_rst),

        .buffer_full_vertex         (M6_2_buffer_full_vertex),
        .finish_read                (M6_2_finish_read),
        .any_dst_data_valid         (M6_2_any_dst_data_valid),
        .tot_src_p_mask             (M6_2_tot_src_p_mask),
        .tot_acc_id                 (M6_2_tot_acc_id),
        .dst_id                     (M6_2_dst_id),
        .src_p_mask_r               (M6_2_src_p_mask_r),
        .dst_data_valid             (M6_2_dst_data_valid));

    get_edge_info_pre_3 M6_3 (
        .clk                        (clk),
        .front_finish_read          (M6_2_finish_read),
        .front_any_dst_data_valid   (M6_2_any_dst_data_valid),
        .front_tot_src_p_mask       (M6_2_tot_src_p_mask),
        .front_tot_acc_id           (M6_2_tot_acc_id),
        .front_dst_id               (M6_2_dst_id),
        .front_src_p_mask_r         (M6_2_src_p_mask_r),
        .front_dst_data_valid       (M6_2_dst_data_valid),
        .back_stage_vertex_full     (M6_4_buffer_full_vertex),

        .front_rst                  (M6_2_rst),
        .rst                        (M6_3_rst),

        .buffer_full_vertex         (M6_3_buffer_full_vertex),
        .finish_read                (M6_3_finish_read),
        .any_dst_data_valid         (M6_3_any_dst_data_valid),
        .tot_src_p_mask             (M6_3_tot_src_p_mask),
        .tot_acc_id                 (M6_3_tot_acc_id),
        .dst_id                     (M6_3_dst_id),
        .src_p_mask_r               (M6_3_src_p_mask_r),
        .dst_data_valid             (M6_3_dst_data_valid));

    get_edge_info_pre_4 M6_4 (
        .clk                        (clk),
        .front_finish_read          (M6_3_finish_read),
        .front_any_dst_data_valid   (M6_3_any_dst_data_valid),
        .front_tot_src_p_mask       (M6_3_tot_src_p_mask),
        .front_tot_acc_id           (M6_3_tot_acc_id),
        .front_dst_id               (M6_3_dst_id),
        .front_src_p_mask_r         (M6_3_src_p_mask_r),
        .front_dst_data_valid       (M6_3_dst_data_valid),
        .back_stage_vertex_full     (M6_5_buffer_full_vertex),

        .front_rst                  (M6_3_rst),
        .rst                        (M6_4_rst),

        .buffer_full_vertex         (M6_4_buffer_full_vertex),
        .finish_read                (M6_4_finish_read),
        .any_dst_data_valid         (M6_4_any_dst_data_valid),
        .tot_src_p_mask             (M6_4_tot_src_p_mask),
        .tot_acc_id                 (M6_4_tot_acc_id),
        .dst_id                     (M6_4_dst_id),
        .src_p_mask_r               (M6_4_src_p_mask_r),
        .dst_data_valid             (M6_4_dst_data_valid));

    get_edge_info_pre_5 M6_5 (
        .clk                        (clk),
        .front_finish_read          (M6_4_finish_read),
        .front_tot_src_p_mask       (M6_4_tot_src_p_mask),
        .front_tot_acc_id           (M6_4_tot_acc_id),
        .front_any_dst_data_valid   (M6_4_any_dst_data_valid),
        .front_dst_id               (M6_4_dst_id),
        .front_src_p_mask_r         (M6_4_src_p_mask_r),
        .front_dst_data_valid       (M6_4_dst_data_valid),
        .back_stage_vertex_full     (M7_buffer_full_vertex),

        .front_rst                  (M6_4_rst),
        .rst                        (M6_5_rst),

        .buffer_full_vertex         (M6_5_buffer_full_vertex),
        .finish_read                (M6_5_finish_read),
        .tot_src_p_mask             (M6_5_tot_src_p_mask),
        .tot_acc_id                 (M6_5_tot_acc_id),
        .any_dst_data_valid         (M6_5_any_dst_data_valid),
        .dst_id                     (M6_5_dst_id),
        .src_p_mask_r               (M6_5_src_p_mask_r),
        .dst_data_valid             (M6_5_dst_data_valid));

    get_edge_info M7 (
        .clk                        (clk),
        .mem_data                   (MEM_IF_mem_data_to_edge_info),
        .mem_data_valid             (MEM_IF_mem_data_valid_to_edge_info),
        .front_finish_read          (M6_5_finish_read),
        .front_tot_src_p_mask       (M6_5_tot_src_p_mask),
        .front_tot_acc_id           (M6_5_tot_acc_id),
        .front_any_dst_data_valid   (M6_5_any_dst_data_valid),
        .front_dst_id               (M6_5_dst_id),
        .front_src_p_mask_r         (M6_5_src_p_mask_r),
        .front_dst_data_valid       (M6_5_dst_data_valid),
        .back_stage_any_full        (M8_buffer_full_any),

        .front_rst                  (M6_5_rst),
        .rst                        (M7_rst),

        .rd_plus_valid              (M7_rd_plus_valid),
        .buffer_full_vertex         (M7_buffer_full_vertex),
        .src_id                     (M7_src_id),
        .src_data_valid             (M7_src_data_valid),
        .tot_src_p_mask             (M7_tot_src_p_mask),
        .tot_acc_id                 (M7_tot_acc_id),
        .any_dst_data_valid         (M7_any_dst_data_valid),
        .dst_id                     (M7_dst_id),
        .src_p_mask_r               (M7_src_p_mask_r),
        .dst_data_valid             (M7_dst_data_valid));

    rd_src_p M8 (
        .clk                        (clk),
        .front_src_id               (M7_src_id),
        .front_src_data_valid       (M7_src_data_valid),
        .front_tot_src_p_mask       (M7_tot_src_p_mask),
        .front_tot_acc_id           (M7_tot_acc_id),
        .front_any_dst_data_valid   (M7_any_dst_data_valid),
        .front_dst_id               (M7_dst_id),
        .front_src_p_mask_r         (M7_src_p_mask_r),
        .front_dst_data_valid       (M7_dst_data_valid),
        .back_stage_edge_full       (M9_2_buffer_full_edge),
        .back_stage_vertex_full     (M9_2_buffer_full_vertex),

        .front_rst                  (M7_rst),
        .rst                        (M8_rst),

        .buffer_full_any            (M8_buffer_full_any),
        .rd_src_p_addr              (M8_rd_src_p_addr),
        .rd_src_p_valid             (M8_rd_src_p_valid),
        .tot_src_p_mask             (M8_tot_src_p_mask),
        .tot_acc_id                 (M8_tot_acc_id),
        .any_dst_data_valid         (M8_any_dst_data_valid),
        .dst_id                     (M8_dst_id),
        .src_p_mask_r               (M8_src_p_mask_r),
        .dst_data_valid             (M8_dst_data_valid));

    /*
    rd_src_p_shuffle_block_1 M9_1 (
        .clk(clk), .rst(rst),
        .front_rd_src_p_addr(M8_rd_src_p_addr), .front_rd_src_p_valid(M8_rd_src_p_valid),
        .front_tot_src_p_mask(M8_tot_src_p_mask), .front_tot_acc_id(M8_tot_acc_id),
        .front_dst_id(M8_dst_id), .front_src_p_mask_r(M8_src_p_mask_r), .front_dst_data_valid(M8_dst_data_valid),
        .back_stage_edge_full(M9_2_buffer_full_edge), .back_stage_vertex_full(M9_2_buffer_full_vertex),

        .buffer_full_edge(M9_1_buffer_full_edge), .buffer_full_vertex(M9_1_buffer_full_vertex),
        .rd_src_p_addr(M9_1_rd_src_p_addr), .rd_src_p_valid(M9_1_rd_src_p_valid),
        .reuse_info(M9_1_reuse_info), .reuse_valid(M9_1_reuse_valid),
        .tot_src_p_mask(M9_1_tot_src_p_mask), .tot_acc_id(M9_1_tot_acc_id),
        .dst_id(M9_1_dst_id), .src_p_mask_r(M9_1_src_p_mask_r), .dst_data_valid(M9_1_dst_data_valid));
    */

    rd_src_p_shuffle_block_2 M9_2 (
        .clk                        (clk),
        .front_rd_src_p_addr        (M8_rd_src_p_addr),
        .front_rd_src_p_valid       (M8_rd_src_p_valid),
        .front_tot_src_p_mask       (M8_tot_src_p_mask),
        .front_tot_acc_id           (M8_tot_acc_id),
        .front_any_dst_data_valid   (M8_any_dst_data_valid),
        .front_dst_id               (M8_dst_id),
        .front_src_p_mask_r         (M8_src_p_mask_r),
        .front_dst_data_valid       (M8_dst_data_valid),
        .back_stage_edge_full       (M9_3_buffer_full_edge),
        .back_stage_vertex_full     (M9_3_buffer_full_vertex),

        .front_rst                  (M8_rst),
        .rst                        (M9_2_rst),

        .buffer_full_edge           (M9_2_buffer_full_edge),
        .buffer_full_vertex         (M9_2_buffer_full_vertex),
        .rd_src_p_addr              (M9_2_rd_src_p_addr),
        .rd_src_p_valid             (M9_2_rd_src_p_valid),
        .req_num                    (M9_2_req_num),
        .tot_src_p_mask             (M9_2_tot_src_p_mask),
        .tot_acc_id                 (M9_2_tot_acc_id),
        .any_dst_data_valid         (M9_2_any_dst_data_valid),
        .dst_id                     (M9_2_dst_id),
        .src_p_mask_r               (M9_2_src_p_mask_r),
        .dst_data_valid             (M9_2_dst_data_valid));

    rd_src_p_shuffle_block_3 M9_3 (
        .clk                        (clk),
        .front_rd_src_p_addr        (M9_2_rd_src_p_addr),
        .front_rd_src_p_valid       (M9_2_rd_src_p_valid),
        .front_req_num              (M9_2_req_num),
        .front_tot_src_p_mask       (M9_2_tot_src_p_mask),
        .front_tot_acc_id           (M9_2_tot_acc_id),
        .front_any_dst_data_valid   (M9_2_any_dst_data_valid),
        .front_dst_id               (M9_2_dst_id),
        .front_src_p_mask_r         (M9_2_src_p_mask_r),
        .front_dst_data_valid       (M9_2_dst_data_valid),
        .back_stage_vertex_full     (M10_buffer_full_vertex),

        .front_rst                  (M9_2_rst),
        .rst                        (M9_3_rst),

        .buffer_full_edge           (M9_3_buffer_full_edge),
        .buffer_full_vertex         (M9_3_buffer_full_vertex),
        .rd_src_p_addr_finish       (M9_3_rd_src_p_addr_finish),
        .rd_src_p_addr              (M9_3_rd_src_p_addr),
        .reorder_loc_y              (M9_3_reorder_loc_y),
        .rd_src_p_valid             (M9_3_rd_src_p_valid),
        .tot_src_p_mask             (M9_3_tot_src_p_mask),
        .tot_acc_id                 (M9_3_tot_acc_id),
        .any_dst_data_valid         (M9_3_any_dst_data_valid),
        .dst_id                     (M9_3_dst_id),
        .src_p_mask_r               (M9_3_src_p_mask_r),
        .dst_data_valid             (M9_3_dst_data_valid));

    rd_src_p_bram_block M10 (
        .clk                        (clk),
        .front_rd_src_p_addr        (M9_3_rd_src_p_addr),
        .front_reorder_loc_y        (M9_3_reorder_loc_y),
        .front_rd_src_p_valid       (M9_3_rd_src_p_valid),
        .front_rd_src_p_addr_finish (M9_3_rd_src_p_addr_finish),
        .front_tot_src_p_mask       (M9_3_tot_src_p_mask),
        .front_tot_acc_id           (M9_3_tot_acc_id),
        .front_any_dst_data_valid   (M9_3_any_dst_data_valid),
        .front_dst_id               (M9_3_dst_id),
        .front_src_p_mask_r         (M9_3_src_p_mask_r),
        .front_dst_data_valid       (M9_3_dst_data_valid),
        .back_stage_vertex_full     (M11_1_buffer_full_vertex),
        // 便于调试，write back 模块扩展地址到 32 位返回
        .wb_dst_addr                (M16_wb_dst_addr),
        .wb_dst_p                   (M16_wb_dst_data),
        .wb_dst_data_valid          (M16_wb_dst_data_valid),

        .front_rst                  (M9_3_rst),
        .rst                        (M10_rst),

        .buffer_full_vertex         (M10_buffer_full_vertex),
        .src_p                      (M10_src_p),
        .reorder_loc_y              (M10_reorder_loc_y),
        .src_p_valid                (M10_src_p_valid),
        .rd_src_p_addr_finish       (M10_rd_src_p_addr_finish),
        .tot_src_p_mask             (M10_tot_src_p_mask),
        .tot_acc_id                 (M10_tot_acc_id),
        .any_dst_data_valid         (M10_any_dst_data_valid),
        .dst_id                     (M10_dst_id),
        .src_p_mask_r               (M10_src_p_mask_r),
        .dst_data_valid             (M10_dst_data_valid));

    rd_src_p_reorder_block_1 M11_1 (
        .clk                        (clk),
        .front_src_p                (M10_src_p),
        .front_reorder_loc_y        (M10_reorder_loc_y),
        .front_src_p_valid          (M10_src_p_valid),
        .front_rd_src_p_addr_finish (M10_rd_src_p_addr_finish),
        .front_tot_src_p_mask       (M10_tot_src_p_mask),
        .front_tot_acc_id           (M10_tot_acc_id),
        .front_any_dst_data_valid   (M10_any_dst_data_valid),
        .front_dst_id               (M10_dst_id),
        .front_src_p_mask_r         (M10_src_p_mask_r),
        .front_dst_data_valid       (M10_dst_data_valid),
        .back_stage_vertex_full     (M11_2_buffer_full_vertex),

        .front_rst                  (M10_rst),
        .rst                        (M11_1_rst),

        .buffer_full_vertex         (M11_1_buffer_full_vertex),
        .src_p                      (M11_1_src_p),
        .src_p_valid                (M11_1_src_p_valid),
        .rd_src_p_addr_finish       (M11_1_rd_src_p_addr_finish),
        .tot_src_p_mask             (M11_1_tot_src_p_mask),
        .tot_acc_id                 (M11_1_tot_acc_id),
        .any_dst_data_valid         (M11_1_any_dst_data_valid),
        .dst_id                     (M11_1_dst_id),
        .src_p_mask_r               (M11_1_src_p_mask_r),
        .dst_data_valid             (M11_1_dst_data_valid));

    rd_src_p_reorder_block_2 M11_2 (
        .clk                        (clk),
        .front_src_p                (M11_1_src_p),
        .front_src_p_valid          (M11_1_src_p_valid),
        .front_rd_src_p_addr_finish (M11_1_rd_src_p_addr_finish),
        .front_tot_src_p_mask       (M11_1_tot_src_p_mask),
        .front_tot_acc_id           (M11_1_tot_acc_id),
        .front_any_dst_data_valid   (M11_1_any_dst_data_valid),
        .front_dst_id               (M11_1_dst_id),
        .front_src_p_mask_r         (M11_1_src_p_mask_r),
        .front_dst_data_valid       (M11_1_dst_data_valid),
        .back_stage_edge_full       (M12_buffer_full_edge),
        .back_stage_vertex_full     (M12_buffer_full_vertex),

        .front_rst                  (M11_1_rst),
        .rst                        (M11_2_rst),

        .buffer_full_vertex         (M11_2_buffer_full_vertex),
        .src_p                      (M11_2_src_p),
        .src_p_valid                (M11_2_src_p_valid),
        .tot_src_p_mask             (M11_2_tot_src_p_mask),
        .tot_acc_id                 (M11_2_tot_acc_id),
        .any_dst_data_valid         (M11_2_any_dst_data_valid),
        .dst_id                     (M11_2_dst_id),
        .src_p_mask_r               (M11_2_src_p_mask_r),
        .dst_data_valid             (M11_2_dst_data_valid));

    /*
    rd_src_p_reorder_block_3 M11_3 (
        .clk(clk), .rst(rst),
        .front_src_p(M11_2_src_p), .front_src_p_valid(M11_2_src_p_valid),
        .front_reuse_info(M11_2_reuse_info), .front_reuse_valid(M11_2_reuse_valid),
        .front_tot_src_p_mask(M11_2_tot_src_p_mask), .front_tot_acc_id(M11_2_tot_acc_id),
        .front_dst_id(M11_2_dst_id), .front_src_p_mask_r(M11_2_src_p_mask_r), .front_dst_data_valid(M11_2_dst_data_valid),
        .back_stage_edge_full(M12_buffer_full_edge), .back_stage_vertex_full(M12_buffer_full_vertex),

        .buffer_full_vertex(M11_3_buffer_full_vertex), .buffer_full_edge(M11_3_buffer_full_edge),
        .src_p(M11_3_src_p), .src_p_valid(M11_3_src_p_valid),
        .tot_src_p_mask(M11_3_tot_src_p_mask), .tot_acc_id(M11_3_tot_acc_id),
        .dst_id(M11_3_dst_id), .src_p_mask_r(M11_3_src_p_mask_r), .dst_data_valid(M11_3_dst_data_valid));
    */

    schedule M12 (
        .clk                        (clk),
        .front_src_p                (M11_2_src_p),
        .front_src_p_valid          (M11_2_src_p_valid),
        .front_tot_src_p_mask       (M11_2_tot_src_p_mask),
        .front_tot_acc_id           (M11_2_tot_acc_id),
        .front_any_dst_data_valid   (M11_2_any_dst_data_valid),
        .front_dst_id               (M11_2_dst_id),
        .front_src_p_mask_r         (M11_2_src_p_mask_r),
        .front_dst_data_valid       (M11_2_dst_data_valid),

        .front_rst                  (M11_2_rst),
        .rst                        (M12_rst),

        .buffer_full_edge           (M12_buffer_full_edge),
        .buffer_full_vertex         (M12_buffer_full_vertex),
        .src_p                      (M12_src_p),
        .src_p_valid                (M12_src_p_valid),
        .src_p_mask                 (M12_src_p_mask),
        .tot_acc_id                 (M12_tot_acc_id),
        .data_valid                 (M12_data_valid),
        .dst_id                     (M12_dst_id),
        .src_p_mask_r               (M12_src_p_mask_r),
        .dst_data_valid             (M12_dst_data_valid));

    edge_process M13 (
        .clk                        (clk),
        .front_src_p                (M12_src_p),
        .front_src_p_valid          (M12_src_p_valid),
        .front_src_p_mask           (M12_src_p_mask),
        .front_tot_acc_id           (M12_tot_acc_id),
        .front_data_valid           (M12_data_valid),
        .front_dst_id               (M12_dst_id),
        .front_src_p_mask_r         (M12_src_p_mask_r),
        .front_dst_data_valid       (M12_dst_data_valid),

        .front_rst                  (M12_rst),
        .rst                        (M13_rst),

        .src_p                      (M13_src_p),
        .tot_acc_id                 (M13_tot_acc_id),
        .src_p_valid                (M13_src_p_valid),
        .dst_id                     (M13_dst_id),
        .src_p_mask_r               (M13_src_p_mask_r),
        .dst_data_valid             (M13_dst_data_valid));

    parallel_accumulator M14 (
        .clk                        (clk),
        .front_src                  (M13_src_p),
        .front_acc_id               (M13_tot_acc_id),
        .front_src_valid            (M13_src_p_valid),
        .front_dst_id               (M13_dst_id),
        .front_src_mask             (M13_src_p_mask_r),
        .front_dst_data_valid       (M13_dst_data_valid),

        .front_rst                  (M13_rst),
        .rst                        (M14_rst),

        .src                        (M14_src),
        .src_valid                  (M14_src_valid),
        .dst_id                     (M14_dst_id),
        .src_mask                   (M14_src_mask),
        .dst_data_valid             (M14_dst_data_valid));

    multiplexer M15 (
        .clk                        (clk),
        .front_src                  (M14_src),
        .front_src_valid            (M14_src_valid),
        .front_dst_id               (M14_dst_id),
        .front_src_mask             (M14_src_mask),
        .front_dst_data_valid       (M14_dst_data_valid),

        .front_rst                  (M14_rst),
        .rst                        (M15_rst),

        .dst_id                     (M15_dst_id),
        .src                        (M15_src),
        .dst_data_valid             (M15_dst_data_valid));

    sequential_accumulator M16 (
        .clk                        (clk),
        .front_dst_id               (M15_dst_id),
        .front_src                  (M15_src),
        .front_dst_data_valid       (M15_dst_data_valid),

        .front_rst                  (M15_rst),
        .rst                        (M16_rst),

        .wb_dst_addr                (M16_wb_dst_addr),
        .wb_dst_data                (M16_wb_dst_data),
        .wb_dst_data_valid          (M16_wb_dst_data_valid));
    
    final_write_back_vertex M17 (
        .clk                        (clk),
        .front_rst                  (M16_rst),
        .rst                        (wr_cn_rst),
        // accelerator signal
        .wr_start                   (acc_done),
        .wr_end                     (1'b0),
        .wb_dst_addr                (M16_wb_dst_addr),
        .wb_dst_data                (M16_wb_dst_data),
        .wb_dst_data_valid          (M16_wb_dst_data_valid),

        // axi signal
        .m_Vertex_Data_axis_tready  (m_Vertex_Data_axis_tready),
        .m_Vertex_Data_axis_tdata   (m_Vertex_Data_axis_tdata),
        .m_Vertex_Data_axis_tvalid  (m_Vertex_Data_axis_tvalid),
        .m_Vertex_Data_axis_tlast   (m_Vertex_Data_axis_tlast),

        .m_Vertex_Id_axis_tready_1  (m_Vertex_Id_axis_tready_1),
        .m_Vertex_Id_axis_tdata_1   (m_Vertex_Id_axis_tdata_1),
        .m_Vertex_Id_axis_tvalid_1  (m_Vertex_Id_axis_tvalid_1),
        .m_Vertex_Id_axis_tlast_1   (m_Vertex_Id_axis_tlast_1),

        .m_Vertex_Id_axis_tready_2  (m_Vertex_Id_axis_tready_2),
        .m_Vertex_Id_axis_tdata_2   (m_Vertex_Id_axis_tdata_2),
        .m_Vertex_Id_axis_tvalid_2  (m_Vertex_Id_axis_tvalid_2),
        .m_Vertex_Id_axis_tlast_2   (m_Vertex_Id_axis_tlast_2),
        
        .m_Vertex_Id_axis_tready_3  (m_Vertex_Id_axis_tready_3),
        .m_Vertex_Id_axis_tdata_3   (m_Vertex_Id_axis_tdata_3),
        .m_Vertex_Id_axis_tvalid_3  (m_Vertex_Id_axis_tvalid_3),
        .m_Vertex_Id_axis_tlast_3   (m_Vertex_Id_axis_tlast_3),

        .m_Vertex_Id_axis_tready_4  (m_Vertex_Id_axis_tready_4),
        .m_Vertex_Id_axis_tdata_4   (m_Vertex_Id_axis_tdata_4),
        .m_Vertex_Id_axis_tvalid_4  (m_Vertex_Id_axis_tvalid_4),
        .m_Vertex_Id_axis_tlast_4   (m_Vertex_Id_axis_tlast_4));

endmodule

